<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2020/1/6} {16:43}
 */

namespace libraries\huawei;

use app\websitext\model\Smsexception;
use app\websitext\model\SmsLog;
use GuzzleHttp\Psr7;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use libraries\errorcode\Code;
use libraries\Tools;
use libraries\Validate;

class HwSms
{
    //默认发送单条短信
    protected $uri = '';
    //APP接入地址
    protected $app_request_url = '';
    //模板ID
    protected $template_id = '';
    //通道
    protected $sender = 'captcha';//默认验证码通道

    public function __construct($template_code = '', $sender = 'captcha', $app_request_url = '', $uri = '')
    {
        $this->uri = $uri?$uri:'/sms/batchSendSms/v1';
        $this->app_request_url = $app_request_url?$app_request_url:'https://rtcsms.cn-north-1.myhuaweicloud.com:10743';
        $this->template_id = $template_code?config('sms.templates_scene')[$template_code]:'';
        $this->sender = $sender?config('sms.sender')[$sender]:'';
    }

    /**
     * desc：$key_code 字符串或数组
     * author：wh
     * @param $mobile
     * @param $key_code
     * @return array
     */
    function send($mobile, $key_code)
    {
        require config('app.ROOT_PATH_PRO').'vendor/autoload.php'; //执行composer install时自动生成
        if(strpos($mobile, ',')){//'13255556666,15566664444,13388887777'
            $mobile_arr = explode(',', $mobile);
            foreach ($mobile_arr as $key=>$m){
                if(false == Validate::is_mobile($m)){
                    return Tools::set_result(1, '存在错误手机号。');
                }
            }
        }else{
            if(false == Validate::is_mobile($mobile)){
                return Tools::set_result(1, '手机号错误');
            }
        }

        //兼容
        //$mobile = (false !== strpos(',',$mobile))?$mobile:'+86'.$mobile;
        //必填,请参考"开发准备"获取如下数据,替换为实际值
        $APP_KEY = config('sms.app_key'); //APP_Key
        $APP_SECRET = config('sms.app_secret');//'q4Ii87BhST9vcs8wvrzN80SfD7Al'; //APP_Secret
        $sender = $this->sender;//'10690400999304165'; //国内短信签名通道号或国际/港澳台短信通道号

        $url = $this->app_request_url.$this->uri; //APP接入地址+接口访问URI
        $TEMPLATE_ID = $this->template_id; //模板ID

        //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
        //国际/港澳台短信不用关注该参数
        $signature = config('sms.signature');////签名名称

        //必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
        $receiver = $mobile;//'+8615123456789,+8615234567890'; //短信接收人号码

        //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
        $statusCallback = '';

        /**
         * 选填,使用无变量模板时请赋空值 $TEMPLATE_PARAS = '';
         * 单变量模板示例:
         *  模板内容为"您的验证码是${NUM_6}"时,$TEMPLATE_PARAS可填写为 '["369751"]'
         * 双变量模板示例:
         *  模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,$TEMPLATE_PARAS可填写为'["3","人民公园正门"]'
         * ${DATE}${TIME}变量不允许取值为空,${TXT_20}变量可以使用英文空格或点号替代空值,${NUM_6}变量可以使用0替代空值
         * 查看更多模板格式规范:产品介绍>模板和变量规范
         * @var string $TEMPLATE_PARAS
         */
        if(is_array($key_code)){
            $key_code_arr = $key_code;
            $TEMPLATE_PARAS = '[';
            foreach ($key_code_arr as $key=>$code){
                $sign = '';
                if($key > 0){
                    $sign = ',';
                }
                $TEMPLATE_PARAS .= $sign.'"'.$code.'"';
            }
            $TEMPLATE_PARAS .= ']';//模板变量
            //$TEMPLATE_PARAS = $key_code;
        }else{
            $TEMPLATE_PARAS = '["'. $key_code .'"]'; //模板变量
        }

        if(empty($TEMPLATE_ID)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' 模板错误');
        }
        if(empty($sender)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' 发送[sender]错误');
        }
        if(empty($TEMPLATE_PARAS)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' 模板参数错误');
        }
        if(empty($signature)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' 签名错误');
        }
        if(empty($APP_KEY)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' APK错误');
        }
        if(empty($APP_SECRET)){
            return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' APS错误');
        }
        $client = new Client();
        try {
            $post_data = [
                'form_params' => [
                    'from' => $sender,
                    'to' => $receiver,
                    'templateId' => $TEMPLATE_ID,
                    'templateParas' => $TEMPLATE_PARAS,
                    'statusCallback' => $statusCallback,//
                    'signature' => $signature //使用国内短信通用模板时,必须填写签名名称
                ],
                'headers' => [
                    'Authorization' => 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
                    'X-WSSE' => $this->buildWsseHeader($APP_KEY, $APP_SECRET)
                ],
                'verify' => false
            ];

            SmsLog::insert($post_data);

            $response = $client->request('POST', $url, $post_data); //为防止因HTTPS证书认证失败造成API调用失败，需要先忽略证书信任问题]);

            SmsLog::insert(Psr7\str($response));
            if($response->getStatusCode() != 200){
                $title = $response->getReasonPhrase();
                Smsexception::insertSmsException($title, $mobile, $key_code, '', '');
                return Tools::set_result(Code::MESSAGE_SEND_ERROR[0], Code::MESSAGE_SEND_ERROR[1].' '.$response->getReasonPhrase());
            }
            return Tools::set_result(Code::SUCCESS[0], Code::SUCCESS[1]);
        } catch (RequestException $e) {
            $title = $e->getMessage();
            $r = $e->hasResponse()?Psr7\str($e->getRequest()):'';
            $exception = $e->getTraceAsString();
            Smsexception::insertSmsException($title, $mobile, $key_code, $exception, $r);
            return Tools::set_result(Code::MESSAGE_SEND_EXCEPTION[0], Code::MESSAGE_SEND_EXCEPTION[1]);
        }
    }
//    function sendNotify($mobile, $key_code_arr)
//    {
//        require config('app.ROOT_PATH_PRO').'vendor/autoload.php'; //执行composer install时自动生成
//        if(false == Validate::is_mobile($mobile)){
//            return Tools::set_result(1, '手机号错误');
//        }
//        if(!is_array($key_code_arr)){
//            return Tools::set_result(1, '通知模板参数错误');
//        }
//        //兼容
//        //$mobile = (false !== strpos(',',$mobile))?$mobile:'+86'.$mobile;
//        //必填,请参考"开发准备"获取如下数据,替换为实际值
//        $APP_KEY = config('sms.app_key'); //APP_Key
//        $APP_SECRET = config('sms.app_secret');//'q4Ii87BhST9vcs8wvrzN80SfD7Al'; //APP_Secret
//        $sender = $this->sender;//'10690400999304165'; //国内短信签名通道号或国际/港澳台短信通道号
//
//        $url = $this->app_request_url.$this->uri; //APP接入地址+接口访问URI
//        $TEMPLATE_ID = $this->template_id; //模板ID
//
//        //条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
//        //国际/港澳台短信不用关注该参数
//        $signature = config('sms.signature');////签名名称
//
//        //必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
//        $receiver = $mobile;//'+8615123456789,+8615234567890'; //短信接收人号码
//
//        //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
//        $statusCallback = '';
//
//        /**
//         * 选填,使用无变量模板时请赋空值 $TEMPLATE_PARAS = '';
//         * 单变量模板示例:
//         *  模板内容为"您的验证码是${NUM_6}"时,$TEMPLATE_PARAS可填写为 '["369751"]'
//         * 双变量模板示例:
//         *  模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,$TEMPLATE_PARAS可填写为'["3","人民公园正门"]'
//         * ${DATE}${TIME}变量不允许取值为空,${TXT_20}变量可以使用英文空格或点号替代空值,${NUM_6}变量可以使用0替代空值
//         * 查看更多模板格式规范:产品介绍>模板和变量规范
//         * @var string $TEMPLATE_PARAS
//         */
//        $tmp_str = '';
//        foreach ($key_code_arr as $key=>$code){
//            $sign = '';
//            if($key > 0){
//                $sign = ',';
//            }
//            $tmp_str .= $sign.'"'.$code.'"';
//        }
//        $TEMPLATE_PARAS = '['.$tmp_str.']';//模板变量
//
//        if(empty($TEMPLATE_ID)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' 模板错误');
//        }
//        if(empty($sender)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' 发送[sender]错误');
//        }
//        if(empty($TEMPLATE_PARAS)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' 模板参数错误');
//        }
//        if(empty($signature)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' 签名错误');
//        }
//        if(empty($APP_KEY)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' APK错误');
//        }
//        if(empty($APP_SECRET)){
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' APS错误');
//        }
//        $client = new Client();
//        try {
//            $post_data = [
//                'form_params' => [
//                    'from' => $sender,
//                    'to' => $receiver,
//                    'templateId' => $TEMPLATE_ID,
//                    'templateParas' => $TEMPLATE_PARAS,
//                    'statusCallback' => $statusCallback,//
//                    'signature' => $signature //使用国内短信通用模板时,必须填写签名名称
//                ],
//                'headers' => [
//                    'Authorization' => 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
//                    'X-WSSE' => $this->buildWsseHeader($APP_KEY, $APP_SECRET)
//                ],
//                'verify' => true
//            ];
////dump($post_data);die;
//            SystemLog::insert($post_data);
//
//            $response = $client->request('POST', $url, $post_data); //为防止因HTTPS证书认证失败造成API调用失败，需要先忽略证书信任问题]);
//
//            if($response->getStatusCode() != 200){
//                $title = $response->getReasonPhrase();
//                Smsexception::insertSmsException($title, $mobile, $key_code_arr, '', '');
//                return Tools::set_result(SystemErrors::MESSAGE_SEND_ERROR[0], SystemErrors::MESSAGE_SEND_ERROR[1].' '.$response->getReasonPhrase());
//            }
//            //echo Psr7\str($response); //打印响应信息
//            //发送记录
//            SmsModel::insertSms($mobile, $key_code_arr);
//            return Tools::set_result(SystemErrors::SUCCESS[0], SystemErrors::SUCCESS[1]);
//        } catch (RequestException $e) {
//            $title = $e->getMessage();
//            $r = $e->hasResponse()?Psr7\str($e->getRequest()):'';
//            $exception = $e->getTraceAsString();
//            Smsexception::insertSmsException($title, $mobile, $key_code_arr, $exception, $r);
//            return Tools::set_result(SystemErrors::MESSAGE_SEND_EXCEPTION[0], SystemErrors::MESSAGE_SEND_EXCEPTION[1]);
//        }
//    }

    /**
     * 构造X-WSSE参数值
     * @param string $appKey
     * @param string $appSecret
     * @return string
     */
    protected function buildWsseHeader(string $appKey, string $appSecret)
    {
        $now = date('Y-m-d\TH:i:s\Z'); //Created
        $nonce = uniqid(); //Nonce
        $base64 = base64_encode(hash('sha256', ($nonce . $now . $appSecret))); //PasswordDigest
        return sprintf("UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"",
            $appKey, $base64, $nonce, $now);
    }

}